package com.svconnect.plugin.builders;

import java.util.List;

import com.svconnect.plugin.model.wsdl.Service;
import com.svconnect.plugin.readers.WSDLParser;
import com.svconnect.plugin.util.Log;

public class ServiceReferenceBuilder extends BuilderBase {

	protected String wsdlURL; 
	protected String packageName;
	
	protected DataContractBuilder contractBuilder;
	protected ServiceClientBuilder clientBuilder;
	protected WebConfigBuilder configBuilder;
	protected DiscoBuilder discoBuilder;
	
	public ServiceReferenceBuilder(String url, String packageName, String refDir) {
		super();
		init(url,packageName,packageName,refDir);
	}
	
	public ServiceReferenceBuilder(String url, String packageName, String dataContractPackageName, String refDir) {
		super();
		init(url,packageName,dataContractPackageName,refDir);
	}
	
	private void init(String url, String packageName, String dataContractPackageName, String refDir) {
		this.wsdlURL = fixWsdlUrl(url);
		this.packageName = packageName;
		this.setReferenceDir(refDir);
		contractBuilder = new DataContractBuilder(dataContractPackageName,this.getReferenceDir());
		clientBuilder = new ServiceClientBuilder(packageName,dataContractPackageName,this.getReferenceDir());
		configBuilder = new WebConfigBuilder(this.getReferenceDir(),packageName);
		discoBuilder = new DiscoBuilder(wsdlURL, this.getReferenceDir());
	}
	
	private String fixWsdlUrl(String url) {
		return url.substring(0,url.lastIndexOf(".svc")+4)+"?wsdl";
	}
	
	@Override
	public void setJavaConventionEnabled(boolean enabled) {
		super.setJavaConventionEnabled(enabled);
		contractBuilder.setJavaConventionEnabled(enabled);
		clientBuilder.setJavaConventionEnabled(enabled);
		configBuilder.setJavaConventionEnabled(enabled);
	}
	
	@Override
	public void setReferenceDir(String dir) {
		super.setReferenceDir(dir);
		if (contractBuilder!=null)
			contractBuilder.setReferenceDir(dir);
		if (clientBuilder!=null)
			clientBuilder.setReferenceDir(dir);
		if (configBuilder!=null)
			configBuilder.setReferenceDir(dir);
	}
	
	public List<Service> discover() {
		try {
			Log.i("Discovering service");
			WSDLParser parser = new WSDLParser(wsdlURL);
			List<Service> services = parser.parse();
			Log.i("Done.");
			return services;
		} catch (Exception e) {
			Log.e(e);
			Log.i("Failed to discover service.");
			return null;
		} 		
	}
	
	public boolean build() {
		try {
			Log.i("Discovering service");
			WSDLParser parser = new WSDLParser(wsdlURL);
			List<Service> services = parser.parse();		
			return this.build(services);
		} catch (Exception e) {
			Log.e(e);
			Log.i("Failed to build clients.");
			return false;
		}   		
	}
	
	public boolean build(List<Service> services) {
		try {
			this.createPackageDir(services, packageName);
			//discoBuilder.build(services);
			contractBuilder.build(services);
			clientBuilder.build(services);
			configBuilder.build(services);
			Log.i("Done.");
			return true;
		} catch (Exception e) {
			Log.e(e);
			Log.i("Failed to build clients.");
			return false;
		}		
	}

}
